﻿using Core.SimpleTemp.Common;
using Core.Toolkit.BaseLibrary.Emit;
using Core.Toolkit.Common;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;

/*----------------------------------------------------------------
* 描述 ：Excel导出帮助类
* 作    者 ：Tengsheng Hou
* 更新时间 ：2019/7/29 8:35:56
//----------------------------------------------------------------*/
namespace Core.Toolkit.Core.Api
{
    [AutoDi(null, AutoDiAttribute.Singleton)]
    public class ExcelHelp
    {
        //readonly WebAppOptions _webAppOptions;
        readonly TempDirDiHelp _tempDirDiHelp;
        ILogger<ExcelHelp> _logger;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="webAppOptions"></param>
        public ExcelHelp(TempDirDiHelp tempDirDiHelp, ILogger<ExcelHelp> logger)
        {
            _tempDirDiHelp = tempDirDiHelp;
            _logger = logger;
        }

        ///// <summary>
        ///// 导出excel 并下载
        ///// </summary>
        ///// <typeparam name="T"></typeparam>
        ///// <param name="dataList"></param>
        ///// <param name="keyValues"></param>
        ///// <param name="path"></param>
        ///// <returns></returns>
        //public ResponseExcelModel CreateAndDownLoad<T>(T dataList, List<KeyValue<string, string>> keyValues) where T : IEnumerable<Object>, IList
        //{
        //    var fileName = TempDirDiHelp.GetTimeStampFielName(".xlsx");
        //    //在模板目录下创建一个已时间戳命名的xlsx文件名 + 路径
        //    var filePath = System.IO.Path.Combine(_tempDirDiHelp.TempDirModel.TempDir, fileName);
        //    //生成Excel
        //    CreateExcel(dataList, keyValues, filePath);
        //    var stream = System.IO.File.OpenRead(filePath);
        //    string fileExt = Path.GetExtension(fileName);
        //    //获取文件的ContentType
        //    var provider = new FileExtensionContentTypeProvider();
        //    var memi = provider.Mappings[fileExt];
        //    //return File(stream, memi, fileName);
        //    return new ResponseExcelModel() { FileStream = stream, ContentType = memi, FileDownloadName = fileName };
        //}

        public string CreateExcel<T>(T _dataList, string path) where T : IEnumerable<Object>, IList
        {
            if (_dataList == null || !_dataList.Any())
                return string.Empty;

            Dictionary<string, PropertyEmit> dicFunc = new Dictionary<string, PropertyEmit>();
            var properties = _dataList[0].GetType().GetProperties();
            var propertyInfosTitle = properties.Where(P => P.Name.EndsWith("_title", StringComparison.InvariantCultureIgnoreCase)).ToList();
            var propertiesOutput = properties.Where(P => !P.Name.EndsWith("_title", StringComparison.InvariantCultureIgnoreCase)).ToList();

            //生成Emit对象
            foreach (var item in properties)
            {
                PropertyEmit propertyEmit = new PropertyEmit(item);
                dicFunc.Add(item.Name, propertyEmit);//仅单次导出缓存Emit对象
            }

            using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
            {
                IWorkbook workbook = new XSSFWorkbook();
                ISheet sheet1 = workbook.CreateSheet("Sheet1");

                #region 设置excel title
                //设置excel title
                IRow rowTitle = sheet1.CreateRow(0);
                var conCount = propertyInfosTitle.Count();
                //单元格样式
                ICellStyle style = workbook.CreateCellStyle();
                style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
                style.FillPattern = FillPattern.SolidForeground;
                for (int i = 0; i < conCount; i++)
                {
                    var titleObj = dicFunc[propertyInfosTitle[i].Name].GetValue(_dataList[0]);
                    var title = Convert.ToString(titleObj);
                    var cell = rowTitle.CreateCell(i);
                    cell.SetCellValue(title);
                    cell.CellStyle = style;
                }
                #endregion

                //设置内容
                var rowCount = _dataList.Count;
                for (int i = 1; i < rowCount + 1; i++)
                {
                    IRow row = sheet1.CreateRow(i);
                    var itemObj = _dataList[i - 1];
                    for (int j = 0; j < conCount; j++)
                    {
                        var conItem = propertyInfosTitle[j];
                        var objValue = dicFunc[conItem.Name.Replace("_title", "", StringComparison.InvariantCultureIgnoreCase)].GetValue(itemObj);
                        string value = Convert.ToString(objValue);
                        row.CreateCell(j).SetCellValue(value);
                    }
                }
                //生成Excel文件
                workbook.Write(fs);

            }
            _logger.LogInformation("创建Excel成功，文件地址{path}", path);
            return path;
        }

        /// <summary>
        /// 导出excel 返回临时文件名称
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataList"></param>
        /// <param name="keyValues"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public string Create<T>(T dataList, string fileName = null) where T : IEnumerable<Object>, IList
        {
            if (dataList == null || !dataList.Any())
                return string.Empty;
            if (string.IsNullOrEmpty(fileName))
                fileName = TempDirHelp.GetTimeStampFielName(".xlsx");
            //在模板目录下创建一个已时间戳命名的xlsx文件名 + 路径
            var filePath = System.IO.Path.Combine(_tempDirDiHelp.TempDirModel.TempDir, fileName);
            //生成Excel
            CreateExcel(dataList, filePath);
            return fileName;
        }

    }

    public class ResponseExcelModel
    {
        public Stream FileStream { get; set; }
        public string ContentType { get; set; }
        public string FileDownloadName { get; set; }
    }


}
